From 4feb1fe2e5bb9f418f51f5f517f70b451159baa2 Mon Sep 17 00:00:00 2001
From: Michael R Sweet <michael.r.sweet@gmail.com>
Date: Mon, 16 Apr 2018 17:16:31 -0400
Subject: [PATCH] - Added a workaround for certain web browsers that do not
 support multiple   authentication schemes in a single response header (Issue
 #5289)

---
 scheduler/client.c | 22 +++++++++++++++++-----
 scheduler/client.h |  8 +++++---
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/scheduler/client.c b/scheduler/client.c
index f388499dc..95c34877d 100644
--- a/scheduler/client.c
+++ b/scheduler/client.c
@@ -813,6 +814,18 @@ cupsdReadClient(cupsd_client_t *con)	/* I - Client to read from */
 
   if (status == HTTP_STATUS_OK)
   {
+   /*
+    * Record whether the client is a web browser.  "Mozilla" was the original
+    * and it seems that every web browser in existence now uses that as the
+    * prefix with additional information identifying *which* browser.
+    *
+    * Chrome (at least) has problems with multiple WWW-Authenticate values in
+    * a single header, so we only report Basic or Negotiate to web browsers and
+    * leave the multiple choices to the native CUPS client...
+    */
+
+    con->is_browser = !strncmp(httpGetField(con->http, HTTP_FIELD_USER_AGENT), "Mozilla/", 8);
+
     if (httpGetField(con->http, HTTP_FIELD_ACCEPT_LANGUAGE)[0])
     {
      /*
@@ -2103,8 +2116,7 @@ cupsdSendHeader(
       strlcpy(auth_str, "Negotiate", sizeof(auth_str));
     }
 
-    if (con->best && auth_type != CUPSD_AUTH_NEGOTIATE &&
-        !_cups_strcasecmp(httpGetHostname(con->http, NULL, 0), "localhost"))
+    if (con->best && auth_type != CUPSD_AUTH_NEGOTIATE && !con->is_browser && !_cups_strcasecmp(httpGetHostname(con->http, NULL, 0), "localhost"))
     {
      /*
       * Add a "trc" (try root certification) parameter for local non-Kerberos
diff --git a/scheduler/client.h b/scheduler/client.h
index aaca8279a..fc7af5400 100644
--- a/scheduler/client.h
+++ b/scheduler/client.h
@@ -26,6 +27,7 @@ struct cupsd_client_s
   struct timeval	start;		/* Request start time */
   http_state_t		operation;	/* Request operation */
   off_t			bytes;		/* Bytes transferred for this request */
+  int			is_browser;	/* Is the client a web browser? */
   int			type;		/* AuthType for username */
   char			username[HTTP_MAX_VALUE],
 					/* Username from Authorization: line */
-- 
2.17.0
